//*** A TYPICAL DANGLING REFRENCE *** 

#include <iostream>  //N.B. no ".h": new-style include.
#include <cstring>
using namespace std; //Everything in 'std' is accessed directly.

//A simple string class.
class SimpleString {
  
public:

  explicit SimpleString(char* data = "");  //Use 'explicit' keyword to disable
                                           //automatic type conversions --
                                           //generally a good idea.

  virtual ~SimpleString();   //Virtual destructor, in case someone inherits
                             //from this class.

  virtual const char* to_cstr() const;  //Get a read-only C string.

  //Many other methods are needed to create a complete string class.
  //This example implements only a tiny subset of these, in order
  //to keep the discussion focused.

  //N.B. no 'inline' methods -- add inlining later, if needed for
  //optimization.

private:
  char* data_p_; //distinguish private class members: a trailing underscore
                 //in the name is one common method
  
};


//Constructor 
SimpleString::SimpleString(char* data_p) :
  data_p_(new char[strlen(data_p)+1]) {
  strcpy(data_p_,data_p);
}

//Destructor
SimpleString::~SimpleString() {
  //N.B. Use of 'delete []' corresponds to previous use of 'new []'.
  //     Using just 'delete' here would be a disaster.
  //delete [] data_p_;
  delete [] data_p_;
  //also try to delete it twice to see what happens

  //you can try that also to see what happens :)
  //delete data_p_;
}

//Returns a read-only C string representation.
const char* SimpleString::to_cstr() const {
  return data_p_;
}


int main() {
  //Create a local SimpleString.
  SimpleString name("O'Reilly Onlamp");

  //Print it out.
  cout << name.to_cstr() << endl;

  //Dynamically create another SimpleString; make it a copy of the local one.
  SimpleString* name_copy_p = new SimpleString(name);
   
  //Print out the copy.
  cout << name_copy_p->to_cstr() << endl;

  //Print out the original again.
  cout << name.to_cstr() << endl;

  //****IMPORTAMT******
  //Delete the copy; set the pointer to null just in case it's used again.
  //Here everything seems fine but there is something to notice
  //name_copy is created with a default copy constructor and when the assignment occurs
  //they share the same data_p member, so when one of them is deleted the other's member is
  //deleted also. The default copy just copies only the pointer doesnt allocate memory for it
  //*****IMPORTANT*******
  delete name_copy_p;
  name_copy_p = 0;
  
  //This looks fine... but the results are highly system-dependent.
  //Bundan sonra ekranda ilginc seyler yazmaya basladi :) ...
  //cout << name.to_cstr() << endl;
}

//*** END: A TYPICAL DANGLING REFERENCE ***
